package scheduled;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
import util.MathUtil;

/**
 * @author
 */
public class CancelSchedule {

    public static CancelSchedule INSTANCE = new CancelSchedule();

    public static int count = 0;

    private Map<String, Future<?>> tasks = new HashMap<>();

    private final ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(1,
        new ThreadFactoryBuilder().setNameFormat("lamp-executor-%d").setDaemon(true).build());

    public static void main(String[] args) throws InterruptedException {

        String task1 = "task1";
        String task2 = "task2";
        INSTANCE.tasks.put(task1, null);
        INSTANCE.tasks.put(task2, null);

        System.out.println(Thread.currentThread() + " first begin");

        INSTANCE.threadPoolExecutor.schedule(task(task1), 1, TimeUnit.SECONDS);

        INSTANCE.threadPoolExecutor.schedule(task(task2), 3, TimeUnit.SECONDS);

        INSTANCE.threadPoolExecutor.schedule(cancelTask(task1), 15, TimeUnit.SECONDS);

//        INSTANCE.threadPoolExecutor.schedule(task(), 3, TimeUnit.SECONDS);

        Thread.sleep(1000 * 600);

    }

    @Test
    private void t1() {
        System.out.println(Thread.currentThread() + ": first begin");
        INSTANCE.threadPoolExecutor.schedule(task("task"), 1, TimeUnit.SECONDS);
    }

    /**
     * 主线程没有了所以不能够在控制台输出
     * @return
     */
    private static Runnable task(String task) {
//        System.out.println(Thread.currentThread() + " 111111");
        return () -> {
//            for (int i = 0; i < 1; i++) {
//                MathUtil.resolvePrime(987654321098765432L);
//            }
            count++;
            System.out.println(task + ": " + count);
            if (count < 50) {
                System.out.println("execute next task");
                ScheduledFuture<?> schedule = INSTANCE.threadPoolExecutor.schedule(task(task), 1, TimeUnit.SECONDS);
                System.out.println(schedule);
                INSTANCE.tasks.replace(task, schedule);
            }
        };
    }

    private static Runnable cancelTask(String task) {

        return () -> {
            System.out.println("cancel execute");
            Future<?> future = INSTANCE.tasks.get(task);
            System.out.println("toString future :" + future);
            future.cancel(true);
        };
    }

}

